package com.zrwl.poscloud.xo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrwl.poscloud.base.entity.FileInfo;
import com.zrwl.poscloud.commons.config.file.FileConfig;
import com.zrwl.poscloud.commons.utils.FileDownloadUtil;
import com.zrwl.poscloud.commons.utils.RandomUtils;
import com.zrwl.poscloud.commons.utils.ResultUtil;
import com.zrwl.poscloud.commons.utils.tool.IpUtil;
import com.zrwl.poscloud.xo.global.MessageConf;
import com.zrwl.poscloud.xo.mapper.FileInfoMapper;
import com.zrwl.poscloud.xo.service.AccessManageService;
import com.zrwl.poscloud.xo.service.FileInfoService;
import com.zrwl.poscloud.xo.service.SyncService;
import com.zrwl.poscloud.xo.vo.FileInfoVO;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;

@Service("FileInfoService")
public class FileInfoServiceImpl extends SuperServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {
    @Autowired
    FileInfoService fileInfoService;
    @Autowired
    FileConfig fileConfig;
    @Autowired
    SyncService syncService;
    @Autowired
    AccessManageService accessManageService;

    String getFileInfoCodeByType(String ownerCode, int type) {
        return ownerCode + type + DateUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + RandomUtils.genSimplePWD();
    }

    @Override
    public FileInfo addFile(FileInfoVO fileInfoVO) {
        FileInfo entity = new FileInfo();
        entity.setFileName(fileInfoVO.getFileInfoName());
        entity.setFileType(fileInfoVO.getFileInfoType());
        entity.setFileSize(fileInfoVO.getFileInfoSize());
        entity.setOwnerCode(fileInfoVO.getOwnerCode());
        entity.setOwnerUid(fileInfoVO.getOwnerUid());
        entity.setLocalFilePath(fileConfig.filePath(fileInfoVO.getOwnerCode(), fileInfoVO.getFileInfoType()));
        if (fileConfig.sync(fileInfoVO.getFileInfoType()))
            entity.setSyncCode(syncService.getUploadSyncCode());//读取本机syncCode
        entity.setStatus(FileConfig.FileStatusEnums.uploading.status);
        entity.setCode(getFileInfoCodeByType(fileInfoVO.getOwnerCode(), fileInfoVO.getFileInfoType()));
        entity.insert();
        return entity;
    }

    @Override
    public String getFileFullPath(FileInfo FileInfo) {
        String fileHeadPath = fileConfig.fullFilePath(FileInfo.getOwnerCode(), FileInfo.getFileType());
        String fileFullPath = fileHeadPath + File.separator;
        return fileFullPath;
    }


    @Override
    public FileInfo findByCode(String FileInfoCode) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", FileInfoCode);
        FileInfo entity = fileInfoService.getOne(queryWrapper);
        return entity;
    }
    @Override
    public void deleteFilesFromDisk() {
        /***
         * 从数据库中查找已删除的文件（根据updateTime找到一个月以前删除的文件），找到文件fullPath，删除文件
         */
        long oneMonthAgoTimestamp = new Date().getTime() - (3600 * 1000 * 24 * 30);
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 0);
        queryWrapper.lt("update_time", oneMonthAgoTimestamp);
        List<FileInfo> deleteFileList = fileInfoService.list(queryWrapper);
        for (int i = 0; i < deleteFileList.size(); i++) {
            FileInfo fileInfo = deleteFileList.get(i);
            String fullFilePath = fileConfig.fullFilePath(fileInfo.getOwnerCode(),fileInfo.getFileType());
            File file = new File(fullFilePath);
            if (file.exists()) {
                if (file.delete()) {
                    fileInfo.setStatus(FileConfig.FileStatusEnums.diskDeleted.status);
                    fileInfo.updateById();
                }
            }
        }
    }

    @Override
    public List<FileInfo> findListBySyncCode(long syncCode) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.gt("sync_code", syncCode);//大于
        List<FileInfo> fileInfoList = fileInfoService.list(queryWrapper);
        return fileInfoList;
    }

    @Override
    public IPage<FileInfo> getFileInfoList(int currentPage, int pageSize) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        Page<FileInfo> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        queryWrapper.eq("status", 1);
        queryWrapper.orderByDesc();
        IPage<FileInfo> pageList = fileInfoService.page(page, queryWrapper);
        List<FileInfo> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }


    @Override
    public String deleteFileInfo(String uid) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", uid);
        FileInfo entity = fileInfoService.getOne(queryWrapper);
        entity.setStatus(FileConfig.FileStatusEnums.deleted.status);
        entity.updateById();
        return "success";

    }

    @Override
    public String recoverFileInfo(String uid) {
        QueryWrapper<FileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("uid", uid);
        FileInfo entity = fileInfoService.getOne(queryWrapper);
        if (entity.getStatus() == FileConfig.FileStatusEnums.diskDeleted.status) {
            throw new RuntimeException("文件已被彻底清理，无法恢复！");
        }
        entity.setStatus(1);
        entity.updateById();
        return "success";
    }

    @Override
    public String getFileByCode(HttpServletRequest request, HttpServletResponse response, String code) {
        /***
         * 0.对ip进行过滤，便于统计结果
         * 1.通过code拿到file实体
         * 2.对实体进行访问统计
         * 3.实现下载
         */

        //获取ip查询授权
        boolean ipAuth = false;
        String ip = IpUtil.getIpAddress(request);
        try {
            accessManageService.enableAccess(ip);
            ipAuth = true;
        } catch (RuntimeException e) {
        }
        FileInfo entity = fileInfoService.findByCode(code);
        if (entity == null) {
            throw new RuntimeException("文件不存在");
        }
        if (entity.getVisitCountsSwitch() == 1) {
            //统计
            accessManageService.saveFileAccess(entity.getUid(), ipAuth, ip);
            entity.setVisitCounts(entity.getVisitCounts() + 1);
            entity.updateById();
        }
        String fullPath = fileInfoService.getFileFullPath(entity)+entity.getFileName();

        FileDownloadUtil.download(fullPath,response);
        return ResultUtil.successWithMessage(MessageConf.DOWNLOAD_SUCCESS);
    }
}